package com.simple.common.utils;

import com.simple.common.exception.RRException;
import org.springframework.http.HttpHeaders;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ProComFileUtil {

    /**
     * 保存文件到指定目录,保存文件并重命名
     * @param file
     * @param basePath
     * @param holdFileName 新的文件名称
     * @return
     */
    public static String saveFile(MultipartFile file,String basePath,String holdFileName){
        String filePath;
        try {
            String originalFilename = file.getOriginalFilename();
            filePath = basePath +holdFileName+"@"+originalFilename;
            File saveFile = new File(filePath);
            if (!saveFile.exists()){
                saveFile.createNewFile();
            }
            file.transferTo(saveFile);
            return filePath;
        }catch (Exception e){
            e.printStackTrace();
            throw new RRException("上传文件失败");
        }
    }

    /**
     * 保存文件到指定目录,保留源文件名
     * @param file
     * @param basePath
     * @return
     */
    public static String saveFile(MultipartFile file,String basePath){
        String filePath;
        try {
            filePath = basePath + file.getOriginalFilename();
            File saveFile = new File(filePath);
            if (!saveFile.exists()){
                saveFile.createNewFile();
            }
            file.transferTo(saveFile);
            return filePath;
        }catch (Exception e){
            e.printStackTrace();
            throw new RRException("上传文件失败");
        }
    }

    public static Boolean deleteFile(String filePath){
        if (filePath == null || filePath.isEmpty()){
            return false;
        }
        File file = new File(filePath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    deleteFile(f.getAbsolutePath());
                }
            }
        }
        return file.delete();
    }

    public static void onlineReadFile(HttpServletResponse response,File file) throws Exception {
        String fileName = URLEncoder.encode(file.getName(),"UTF-8");
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=" + fileName);
        // 将本地文件写入响应输出流
        OutputStream outputStream = response.getOutputStream();
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fileInputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, len);
        }
        fileInputStream.close();
        outputStream.close();
    }

    /**
     * 压缩打包下载
     * @param response
     * @param params key是文件夹名称,value是一个list<String> 文件路径
     * @throws Exception
     */
    public static void downloadZipFile(HttpServletResponse response, Map<String, Object> params) throws Exception {
        String projectName = String.valueOf(params.get("projectName"));
        params.remove("projectName");
        // 创建一个临时文件用于存储 ZIP 文件
        File tempFile = File.createTempFile("temp", ".zip");

        // 压缩文件
        FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
        ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String category = entry.getKey();
            List<String> fileAddresses = (List<String>)entry.getValue();

            if (fileAddresses.isEmpty()) {
                continue; // 如果该分类下没有文件，则跳过
            }

            // 如果只有一个分类，则将所有文件放在 ZIP 根目录中
            String folderPath = category.isEmpty() ? "" : (category + File.separator);

            // 将文件复制到对应的文件夹并添加到 ZIP 压缩流中
            for (String fileAddress : fileAddresses) {
                File file = new File(fileAddress);
                ZipEntry zipEntry = new ZipEntry(folderPath + file.getName());
                zipOutputStream.putNextEntry(zipEntry);

                FileInputStream fis = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }
                fis.close();
            }
        }

        // 关闭流
        zipOutputStream.close();
        fileOutputStream.close();
        String zipFileName = projectName == null || "".equals(projectName) || "null".equals(projectName)?
                "文件.zip":projectName + ".zip";

        // 设置 Response 头信息
        response.setContentType("application/zip");
        zipFileName = URLEncoder.encode(zipFileName,"UTF-8");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=" + zipFileName);

        // 将 ZIP 文件写入 Response 输出流
        OutputStream outputStream = response.getOutputStream();
        FileInputStream fileInputStream = new FileInputStream(tempFile);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fileInputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, len);
        }
        outputStream.flush();
        outputStream.close();
        fileInputStream.close();

        // 删除相关文件夹和文件
        for (String category : params.keySet()) {
            if (category.isEmpty()) {
                continue;
            }
            String folderPath = category + File.separator;
            deleteFile(folderPath);
        }
        // 删除临时文件
        tempFile.delete();
    }

}
